package com.ebrothers.isns.activity;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.location.Location;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.ebrothers.isns.NavigationManager;
import com.ebrothers.isns.R;
import com.ebrothers.isns.NavigationManager.NavigatedView;
import com.ebrothers.isns.NavigationManager.OnNavigationListener;
import com.ebrothers.isns.common.Constants;
import com.ebrothers.isns.common.PrefsManager;
import com.ebrothers.isns.common.PrefsManager.Keys;
import com.ebrothers.isns.controller.ViewController;
import com.ebrothers.isns.data.JsonParser;
import com.ebrothers.isns.data.QsInteractor;
import com.ebrothers.isns.map.NetworkLocator;
import com.ebrothers.isns.map.Locator.OnLocationInfoRetrievedListener;
import com.ebrothers.isns.map.NetworkLocator.OnLocatedListener;
import com.ebrothers.isns.view.ViewStack;
import com.ebrothers.isns.vo.Answer;
import com.ebrothers.isns.vo.Question;
import com.ebrothers.isns.vo.User;
import com.google.android.maps.MapActivity;

public class ISNSMain extends MapActivity {
	private static final String TAG = "ISNSMain";
	private static final int DIALOG_POST_PROGRESSING = 0;
	private static final int DIALOG_LOCATING = 1;
	private static final int DIALOG_CONFIRM_EXIT = 2;
	private NavigationManager mNavManager;
	private ViewStack mViewStack;
	private TextView mBody;
	private TextView mName;
	private TextView mAddress;
	private Button mQ;
	private Button mLocate;
	private NetworkLocator mLocator;

	@Override
	protected void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.isns_main);
		updateLocation();
		mNavManager = NavigationManager.getInstance();
		mViewStack = (ViewStack) findViewById(R.id.view_stack);
		mNavManager.represent(this, mViewStack);
		mNavManager.setOnNavigationListener(new OnNavigationListener() {
			public void onNavigation(NavigatedView view) {
				if (Constants.LOGD) {
					Log.d(TAG, "****** onNavigation. view=" + view);
				}
			}
		});
		mBody = (TextView) findViewById(R.id.body);
		mName = (TextView) findViewById(R.id.name);
		mAddress = (TextView) findViewById(R.id.location);

		findViewById(R.id.btn_post).setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				if (TextUtils.isEmpty(mBody.getText())) {
					Toast
							.makeText(
									getApplicationContext(),
									"Please input text body before posting a Qestion or an Answer .",
									Toast.LENGTH_SHORT).show();
				} else {
					showDialog(DIALOG_POST_PROGRESSING);
					new Thread() {
						@Override
						public void run() {
							if (mNavManager
									.isNavigatedView(NavigatedView.VIEW_QS)) {
								postAQuestion();
							} else if (mNavManager
									.isNavigatedView(NavigatedView.VIEW_AS)) {
								postAnAnswer();
							}
							mNavManager.getCurrentController().requestRefresh();
							removeDialog(DIALOG_POST_PROGRESSING);
						}
					}.start();
				}
			}
		});
		mLocate = (Button) findViewById(R.id.btn_locat_me);
		mLocate.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				invalidateButtons(v);
				mNavManager.navigateTo(NavigatedView.VIEW_MAP, null, true);
			}
		});
		mQ = (Button) findViewById(R.id.btn_q);
		mQ.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				invalidateButtons(v);
				NavigationManager.getInstance().navigateTo(
						NavigatedView.VIEW_QS, null, false);
			}
		});
	}

	private void updateLocation() {
		mLocator = new NetworkLocator(getApplicationContext());
		mLocator.setOnLocatedListener(new OnLocatedListener() {
			public void onLocated(final Location location) {
				if (Constants.LOGD) {
					Log.d(TAG, "****** onLocated. ");
				}
				mLocator.requestAddressInfoByLocation(location,
						new OnLocationInfoRetrievedListener() {
							public void onLocationInfoRetrieved(String json) {
								dismissDialog(DIALOG_LOCATING);
								final String address = JsonParser
										.parseAddressInfo(json);
								runOnUiThread(new Runnable() {
									public void run() {
										mAddress.setText(address);
										Toast.makeText(
												getApplicationContext(),
												"Your current location is ["
														+ address + "].",
												Toast.LENGTH_SHORT).show();
									}
								});
								PrefsManager pm = PrefsManager
										.getInstance(getApplicationContext());
								pm.edit();
								pm.putString(Keys.LAST_LOCATION_NAME, address);
								pm
										.putString(
												Keys.LAST_LOCATION_LONGITUDE,
												String.valueOf(location
														.getLongitude()));
								pm.putString(Keys.LAST_LOCATION_LATITUDE,
										String.valueOf(location.getLatitude()));
								pm.commit();
							}
						});
			}

			public void onLocateFaild() {
				if (Constants.LOGD) {
					Log.d(TAG, "****** onLocateFaild. ");
				}
				dismissDialog(DIALOG_LOCATING);
				Toast
						.makeText(
								getApplicationContext(),
								"Can't locate your position via network, please check network.",
								Toast.LENGTH_SHORT).show();
			}
		});

		showDialog(DIALOG_LOCATING);
		mLocator.locate();
	}

	private void invalidateButtons(View v) {
		if (v.equals(mLocate)) {
			mLocate.setBackgroundResource(R.drawable.ic_locate_press);
			mQ.setBackgroundResource(R.drawable.ic_q_rest);
		} else if (v.equals(mQ)) {
			mLocate.setBackgroundResource(R.drawable.ic_locate_rest);
			mQ.setBackgroundResource(R.drawable.ic_q_press);
		}
	}

	private void postAQuestion() {
		final PrefsManager pm = PrefsManager
				.getInstance(getApplicationContext());
		final String locName = pm.getString(Keys.LAST_LOCATION_NAME, "");
		final String longitude = pm.getString(Keys.LAST_LOCATION_LONGITUDE, "");
		final String latitude = pm.getString(Keys.LAST_LOCATION_LATITUDE, "");
		if (TextUtils.isEmpty(locName) || TextUtils.isEmpty(longitude)
				|| TextUtils.isEmpty(latitude)) {
			runOnUiThread(new Runnable() {
				public void run() {
					Toast
							.makeText(
									getApplicationContext(),
									"There is no your location information, please locate your location before posting a Question.",
									Toast.LENGTH_SHORT).show();
				}
			});
			return;
		}
		Question q = new Question();
		q.owner = new User();
		q.owner.name = mName.getText().toString();
		q.triggerLocation = new com.ebrothers.isns.vo.Location();
		q.triggerLocation.name = locName;
		q.triggerLocation.longitude = longitude;
		q.triggerLocation.latitude = latitude;
		q.body = mBody.getText().toString();
		QsInteractor.newAQuestion(q);
	}

	private void postAnAnswer() {
		final PrefsManager pm = PrefsManager
				.getInstance(getApplicationContext());
		final String locName = pm.getString(Keys.LAST_LOCATION_NAME, "");
		final String longitude = pm.getString(Keys.LAST_LOCATION_LONGITUDE, "");
		final String latitude = pm.getString(Keys.LAST_LOCATION_LATITUDE, "");
		if (TextUtils.isEmpty(locName) || TextUtils.isEmpty(longitude)
				|| TextUtils.isEmpty(latitude)) {
			runOnUiThread(new Runnable() {
				public void run() {
					Toast
							.makeText(
									getApplicationContext(),
									"There is no your location information, please locate your location before posting an Answer.",
									Toast.LENGTH_SHORT).show();
				}
			});
			return;
		}
		Answer a = new Answer();
		a.body = mBody.getText().toString();
		a.owner = new User();
		a.owner.name = mName.getText().toString();
		Question q = (Question) mNavManager.getCurrentController().getData()
				.get("q");
		a.question = q;
		a.triggerLocation = new com.ebrothers.isns.vo.Location();
		a.triggerLocation.name = locName;
		a.triggerLocation.longitude = longitude;
		a.triggerLocation.latitude = latitude;
		QsInteractor.answerAQuestion(a);
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_POST_PROGRESSING:
			ProgressDialog dialog = new ProgressDialog(this);
			if (mNavManager.isNavigatedView(NavigatedView.VIEW_QS)) {
				dialog.setMessage("Posting a Q");
			} else if (mNavManager.isNavigatedView(NavigatedView.VIEW_AS)) {
				dialog.setMessage("Posting an A");
			}
			dialog.show();
			return dialog;
		case DIALOG_LOCATING:
			dialog = new ProgressDialog(this);
			dialog.setMessage("Locate your position...");
			dialog.show();
			return dialog;
		case DIALOG_CONFIRM_EXIT:
			return new AlertDialog.Builder(this).setMessage(
					"Are you sure you want to exit?").setPositiveButton(
					android.R.string.yes,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog, int which) {
							finish();
						}
					}).setNegativeButton(android.R.string.no, null).show();
		default:
			break;
		}
		return super.onCreateDialog(id);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (KeyEvent.KEYCODE_BACK == keyCode) {
			if (mViewStack.isOnTop()) {
				showDialog(DIALOG_CONFIRM_EXIT);
			} else {
				NavigationManager.getInstance().navigateTo(
						NavigatedView.VIEW_QS, null, false);
			}
			return true;
		}
		return super.onKeyDown(keyCode, event);
	}

	@Override
	protected void onResume() {
		final ViewController controller = mNavManager.getCurrentController();
		if (controller != null) {
			controller.onResume();
		}
		if (Constants.LOGD) {
			Log.d(TAG, "****** onResume. controller=" + controller);
		}
		super.onResume();
	}

	@Override
	protected void onPause() {
		if (Constants.LOGD) {
			Log.d(TAG, "****** onPause. ");
		}
		final ViewController controller = mNavManager.getCurrentController();
		if (controller != null) {
			controller.onPause();
		}
		super.onPause();
	}

	@Override
	protected void onDestroy() {
		final ViewController controller = mNavManager.getCurrentController();
		if (controller != null) {
			controller.onDestroy();
		}
		super.onDestroy();
	}

	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

}
